<?php
/**
 * This file provides {@link Domain51_App_Js}
 *
 * @package     Domain51
 * @subpackage  Domain51_App_Js
 */

/**
 * Load super-class file
 */
Solar::loadClass('Solar_Controller_Page');


/**
 * Provides an interface to {@link HTML_AJAX_Server::handleRequest()}.
 *
 * This serves two purposes:
 *  - Exposing PHP objects to AJAX requests
 *  - Exposing internal Javascript libraries
 *
 * Javascript libraries can be configured by setting the  
 *  <code>
 *      $config['Domain51_App_Js']['js_libraries'][] = array(
 *          'libraryName'   => 'library',
 *          'fileName'      => 'library.js',
 *          'path'          => '/path/to/library/'
 *      );
 *  </code>
 *
 * The library would be access via the following URL:
 *  <code>
 *      index.php/js/?client=library
 *  </code>
 *
 * @author      Travis Swicegood <development [at] domain51 [dot] com>
 * @package     Domain51
 * @subpackage  Domain51_App_Js
 * @license     Released under the same license as Solar
 */
class Domain51_App_Js extends Solar_Controller_Page
{
    /**
     * Provide the base configuration values for this object.
     *
     * `pack_javascript`
     * : (boolean)  Should JavaScript code be stripped of whitespace
     *
     * `js_libraries`
     * : (array)    An array of JavaScript libraries to load.  The format 
     *      follows the naming convention of
     *      {@link HTML_AJAX_Server::registerJSLibaries()}.
     *      `libraryName`
     *          : (string)
     *              The name the library will be referenced by
     *      `fileName`
     *          : (string)  
     *              The name of the JS file to load when libraryName is
     *              requested.
     *      `path`
     *          : (string|false)
     *              If not false, the path to where fileName is located
     *
     * `init_objects`
     * : (array)
     *      An array of HTML_AJAX init objects.
     *
     * `classes`
     * : (array)
     *      An array of arrays containing data necessary to load a particular
     *      class and make it accessible to an AJAX call.  The keys are named
     *      to match {@link HTML_AJAX_Server::registerClass()} with the 
     *      exception of name instead of instance.
     *      `name` : (string)
     *          The name of the object to load via {@link Solar::factory()}
     *      `exportedName` : (string|false)
     *          The name to register this object with, if not false
     *      `exportedMethods` : (array|false)
     *          An array of the method names to export, if not false
     *
     * @var     array
     * @access  protected
     */
    protected $_Domain51_App_Js = array(
        'pack_javascript' => false,
        'js_libraries' => array(),
        'init_objects'  => array(),
        'classes' => array(),
    );
    
    
    /**
     * Specifies that {@link actionServer()} is the action that should be 
     * called if nothing is specified.
     *
     * @var     string
     * @access  protected
     * @see     actionServer()
     */
    protected $_action_default = 'server';
    
    
    /**
     * Creates an HTML_AJAX server file to handle AJAX requests
     *
     * @return  void
     * @access  public
     */
    public function actionServer() {
        // include the server class
        include 'HTML/AJAX/Server.php';
        
        // create our new server
        $server = new HTML_AJAX_Server();
        
        // Set packJavaScript property
        $server->ajax->packJavaScript = $this->_config['pack_javascript'];
        
        // Load all known JS libraries
        foreach ($this->_config['js_libraries'] as $info) {
            $server->registerJSLibrary(
                $info['libraryName'],
                $info['fileName'],
                $info['path']
            );
        }
        
        // If any init_objects are specified, turn initMethods on and load the
        // init objects.
        if (count($this->_config['init_objects']) > 0) {
            $server->initMethods = true;
            foreach ($this->_config['init_objects'] as $name) {
                $instance = Solar::factory($name);
                $server->registerInitObject($instance);
            }
        }
        
        // Register all classes that have been explicitly defined by the config.
        foreach ($this->_config['classes'] as $class) {
            if (!isset($class['exportedName'])) {
                $class['exportedName'] = false;
            }
            if (!isset($class['exportedMethods'])) {
                $class['exportedMethods'] = false;
            }
            
            $instance = Solar::factory($class['name']);
            $server->registerClass($instance, $class['exportedName'], $class['exportedMethods']);
        }
        
        // handle different types of requests possiblities are
        // ?client=all - request for all javascript client files
        // ?stub=classname - request for proxy stub for given class, can be combined with client but this may hurt caching unless stub=all is used
        // ?c=classname&m=method - an ajax call, server handles serialization and handing things off to the proper method then returning the results
        $server->handleRequest();
    }
    
    
    /**
     * Override the default {@link Solar_Controller_Page::_render()} to prevent
     * an attempt to load templates.
     *
     * @return void
     */
    protected function _render() { 
        
    }
}

?>
